<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>内置构造函数————数组</title>
</head>
<body>
<!--
基本数据类型:
    String  num  Boolean  undefined  null
    这些类型都被JS底层做了构造函数的包装，因此可以使用构造函数的方法和属性（当然属性就是他自己）

引用数据类型:
    Object: Object是内置的构造函数，用于创建普通对象
            推荐使用字面量的方式声明对象，而不是Object构造函数
            三个静态常用方法: 静态方法就是只有构造函数Object可以调用的
    Array: Array是内置的构造函数，用于创建数组
           创建数组建议用字面量创建，不用Array构造函数创建
           四个静态常用方法
-->
<script>
    const str = 'pink'
    console.log(str)
    console.log(str.length)
// Object
    const user = new Object({name: '小明' , age: 15})
    // 三个静态方法
    for (const userKey in user) {
        console.log(userKey) // 属性: name , age
        console.log(user[userKey]) // 值: '小明' , 15
    }
    // 1.获得所有的属性名
    console.log(Object.keys(user)) // 返回数组[ 'name' , 'age' ]
    // 2.获得所有的属性值
    console.log(Object.values(user)) // 返回数组[ '小明' , 15 ]
    // 3.拷贝对象 ———— 深拷贝
    const newUser = {}
    Object.assign(newUser , user) // 把user 拷贝给 newUser
        // 使用场景: 给对象添加属性
    Object.assign(user , {gender : '女'})
    console.log(user)
    console.log(newUser)

// Array
    const array = ['Black' , 'Pink' , 'White']
    console.log(array)
    // 四个静态方法
    // forEach方法————遍历数组
    array.forEach(function (value, index, array) {
        /*
        * 参数说明：
        *   value: 必须，当前元素的值
        *   index: 可选，获取当前元素在数组中的索引值
        *   array: 当前元素所处的数组对象
        * */
        /*
        * forEach方法特点:
        *   循环次数 === 数组长度
        *   每一次循环都会执行一次函数体，省略了for的书写
        *   函数内部没有return值 , forEach方法也没有返回值
        * */
        /*
        * forEach方法注意点:
        *   forEach()对于空数组是不会执行回调函数的
        *   forEach()是不支持 continue 与 break 语句的，可以使用return语句来实现continue的效果
        * */
        console.log(value) // 数组值
        console.log(index) // 数组索引
        console.log(array) // 父亲数组号
    })

    // filter方法————过滤数组
     const array4 = array.filter(function (value, index, array) {
        /*
        * 参数说明：
        *   value: 必须，当前元素的值
        *   index: 可选，当前元素在数组中的索引值
        *   array: 当前元素所处的数组对象
        * */
        /*
        * forEach方法特点:
        *   循环次数 === 数组长度
        *   每一次循环都会执行一次函数体，省略了for的书写
        *   函数内部有return值
        *       return true: 满足条件,将新的元素放入新数组中
        *       return false: 不满足条件返回null
        *       (如果遍历完所有的元素发现没有符合条件的，就返回空数组)
        * */
        /*
        * forEach方法注意点:
        *   filter()方法不会对空数组进行检测
        *   filter()方法不会改变元素原始数组
        * */
        if (index <= 1)
            return true
        else
            return false
    })
    console.log(array4)
    const array5 = array.filter(function (value, index, array) {
        // 简写
        return index <= 1;
    })
    console.log(array5)
    // 进一步简写
    const array6 = array.filter((value, index) =>  index <= 1)
    console.log(array6)

    // map方法————迭代数组(迭代数组比过滤数组范围要大)
    const array7 = array.map(function (value, index, array) {
      /*
       * 参数说明：
       *   value: 必须，当前元素的值
       *   index: 可选，当前元素在数组中的索引值
       *   array: 当前元素所处的数组对象
       * */
        /*
        * forEach方法特点:
        *   循环次数 === 数组长度
        *   每一次循环都会执行一次函数体，省略了for的书写
        *   函数内部有return值
        *       return 元素: 满足条件的元素放入新数组中
        *       return false: 不满足条件的元素不放入新数组
        *       (如果遍历完所有的元素发现没有符合条件的，就返回空数组)
        * */
        /*
        * forEach方法注意点:
        *   filter()方法不会对空数组进行检测
        *   filter()方法不会改变元素原始数组
        * */
        console.log(value + "haha")
        return value + "haha"
    })
    console.log(array7)
    // 累加器，数组中的每个值（从左到右）开始缩减，最终计算为一个值
    const initValue = "Pink"
    const String = array.reduce((previousValue, currentValue, currentIndex, array) => {
        /*
        * previousValue: 上一次调用函数的返回值
        * value: 当前元素
        * index: 当前元素索引
        * array: 当前元素所处的数组对象
        * initValue: 数组操作之前的初始值，在没开始加和时最开始的结构
        * */
        /*
        * 1. 如果有起始值，就把初始值累加到里面
        * */
        console.log(previousValue)
        console.log(currentValue)
        console.log(currentIndex)
        console.log(array)

        return previousValue + currentValue
    } , initValue)
    console.log(String)
    // 箭头函数的写法
    const String1 = array.reduce((previousValue, currentValue, currentIndex, array1) => previousValue + currentValue , 10)
    console.log(String1)
    // 实例
    const arr = [{
        name: '张三',
        salary: 10000
    } , {
        name: '李四',
        salary: 10000
    } , {
        name: '王五',
        salary: 10000
    }]
    const sum = arr.reduce((previousValue, currentValue) => previousValue + currentValue.salary , 0 )
    // 当数组的元素是对象时，preciousValue确实是数字，这时必须让初始值为0（不然上一个元素就变对象了） ，同时currentValue是当前对象，需要把他取一个salary才能用
    console.log(sum)
    const sum1 = arr.reduce((previousValue, currentValue) => {
       return (previousValue + currentValue.salary * 1.1)
    } , 0)
    console.log(sum1)
    /*
    * 其他方法:
    *   join: 数组元素拼接为字符串，返回字符串（重点）
    *   find: 查找元素，返回符合测试条件的第一个数组元素值，没有符合的就返回undefined
    *   every: 检测数组所有元素是否符合指定条件，如果所有元素都通过就返回true，否则就返回false
    *   some: 检测数组元素是否满足指定条件，如果有元素满足就返回ture，否则就返回false
    *   concat: 合并两个数组，返回生成新数组
    *   sort: 对原数组单元值排序
    *   splice: 删除挥着替换原数组单元
    *   reverse: 反转数组
    *   findIndex: 查找元素的索引值
    * */
    // join方法————拼接数组
    /*
    * join()方法用于把数组中的所有元素拼成一个字符串
    * 语法:
    *     arr.join('参数') // red颜色 blue颜色 green颜色
    * 参数:
    *    数组元素是通过参数里面指定的分隔符进行分割的，空字符串('')，则所有元素之间都没有任何字符
    * */
    // 小括号为空则为逗号(,)分割
    console.log(arr.join())
    // 小括号是空字符串，则颜色间没有分隔符
    console.log(arr.join(''))
    // 小括号里面是啥就用啥分隔符
    console.log(arr.join('|'))
    // find方法————查找元素，返回符合条件的第一个元素值
    const arr8 = [
        {
            name: '小米',
            price: 1999
        },
        {
            name: '华为',
            price: 3999
        },
        {
            name: '荣耀',
            price: 3333
        }
    ]
    // find方法————找到查询到的第一个符合条件的数组元素，并把该对象返回
    const mi = arr8.find(function (value, index, obj) {
         /*
          * 参数说明：
          *   value: 必须，当前元素的值
          *   index: 可选，当前元素在数组中的索引值
          *   obj: 当前元素所处的数组对象
          * */

        console.log(value)
        console.log(index)
        console.log(obj)
        return value.name === '小米'
    } )
    console.log(mi)
    const ron = arr8.find(value => value.name === '荣耀')
    console.log(ron)
    // every方法————检测数组中的元素是不是都符合条件，如果都符合就返回true，否则就返回false
    const arr1 = [10 , 20 , 30]
    const flag = arr1.every(item => item >= 10)
    console.log(flag)
    // some方法————检测数组中的元素是否有满足条件的，如果有就返回true,否则就返回false
    const flag2 = arr1.some(item => item <= 30)
    console.log(flag2)
    // from方法————伪数组转换成真数组
    // const trueLis = Array.from(falseLis)

</script>
</body>
</html>